package com.cndym.utils;

import java.util.ArrayList;
import java.util.List;

/**
 * User: lfx
 * Date: 11-12-30 下午2:31
 */
public class CombinUtils {
    /**
     * N个数以M个元素为一组排列，return总共能排列的次数
     *
     * @param m
     * @param n
     * @return
     */
    public static int getCount(int m, int n) {
        int sum;
        int i;
        if (m == n) return 1;
        if (0 == m || 0 == n || m > n) return 0;
        sum = 1;
        if (2 * m < n) m = n - m;
        i = m + 1;
        while (i <= n) {
            sum *= i;
            i++;
        }
        i = n - m;
        while (i > 1) {
            sum /= i;
            i--;
        }
        return sum;
    }

    /**
     * N个数以M个元素为一组排列，return相同数字出现的次数
     * @param m
     * @param n
     * @return
     */
    public static int getCountLikeNum(int m,int n){
        return getCount(m,n) * m / n;
    }


    public static void main(String[] args) {
//        System.out.println("start");
////        List<int[]> list = sf(3,4);
//        List<int[]> list = createCombinationIndex(2,3);
//        for(int [] numArray : list){
//            for (int num : numArray){
//                System.out.print(num + " ");
//            }
//            System.out.println();
//        }
//        System.out.println("stop");
//        createCombinationIndex(2,4);

//        for (int[] t : createCombination(2, 5)) {
//            for (int a : t) {
//                System.out.print(a);
//            }
//            System.out.println();
//        }

        System.out.println(getCount(2,6));
    }


    /**
     * 次函数为私有，不需要人为调用
     * 是下面createCombinationIndex,createCombination函数需要封装的递归方法
     *
     * @param i
     * @param j
     * @param min
     * @param max
     * @param intArray
     * @param index
     * @param list
     */
    private static void createCombinationIndexFun(int i, int j, int min, int max, int[] intArray, int index, List<int[]> list) {
        for (; i <= j; i++) {
            intArray[index] = i;
            if (max == j) {
                list.add(intArray.clone());
            } else {
                createCombinationIndexFun(i + 1, j + 1, min, max, intArray, index + 1, list);
            }
        }
    }


    /**
     * N个数以M个元素为一组排列，得出所有排列的索引集合
     *
     * @param m
     * @param n
     */
    public static List<int[]> createCombinationIndex(int m, int n) {
        List<int[]> list = new ArrayList<int[]>();
        int[] c = new int[m];
        createCombinationIndexFun(0, n - m, m, n - 1, c, 0, list);
        return list;
    }

    /**
     * N个数以M个元素为一组排列，得出所有排列的数值集合
     *
     * @param m
     * @param n
     * @return
     */
    public static List<int[]> createCombination(int m, int n) {
        List<int[]> list = new ArrayList<int[]>();
        int[] c = new int[m];
        createCombinationIndexFun(1, n - m + 1, m, n, c, 0, list);
        return list;
    }

    /**
     * 将字符串str以splic为分隔符分解成字符串数组，并将字符串数组转换成int数组返回
     * 异常未捕获，在上层应该做相应的处理
     *
     * @param str
     * @param split
     * @return
     */
    public static int[] strToIntArray(String str, String split) {
        if (null == str || "".equals(str.trim())) {
            return null;
        }
        String[] strArray = str.trim().split(split);
        int[] num = new int[strArray.length];
        for (int i = 0; i < strArray.length; i++) {
            num[i] = Integer.parseInt(strArray[i]);
        }
        return num;
    }

    /**
     * 将一个整数分解成一个整数数组
     * 例： num=123;  -->  numArray[3]{1,2,3}
     *
     * @param num
     * @return
     */
    public static int[] intToIntArray(int num) {
        String[] strArray = String.valueOf(num).trim().split("");
        int[] numArray = new int[strArray.length - 1];
        for (int i = 1; i < strArray.length; i++) {
            numArray[i - 1] = Integer.parseInt(strArray[i]);
        }
        return numArray;
    }

    /**
     * 将一个整数字符串分解成一个整数数组
     * 例： num=123;  -->  numArray[3]{1,2,3}
     *
     * @param num
     * @return
     */
    public static int[] strToIntArray(String num) {
        String[] strArray = num.trim().split("");
        int[] numArray = new int[strArray.length - 1];
        for (int i = 1; i < strArray.length; i++) {
            numArray[i - 1] = Integer.parseInt(strArray[i]);
        }
        return numArray;
    }

    public static String strToStrOfSplit(String num,String split){
        StringBuffer stringBuffer = new StringBuffer();
        String[] strArray = num.trim().split("");
        for (int i = 1; i < strArray.length; i++) {
            stringBuffer.append(strArray[i]);
            if(i != strArray.length - 1){
                stringBuffer.append(split);
            }
        }
        return stringBuffer.toString();
    }


    /**
     * 检查两个整形数组相同元素的个数
     *
     * @param x
     * @param y
     * @return
     */
    public static int getArrSameArrCount(int[] x, int[] y) {
        int count = 0;
        for (int i = 0; i < x.length; i++) {
            for (int j = 0; j < y.length; j++) {
                if (x[i] == y[j]) {
                    count++;
                }
            }
        }
        return count;
    }

    /**
     * 冒泡排序
     *
     * @param num
     * @return
     */
    public static int[] maopao(int[] num) {
        int temp;
        for (int i = 0; i < num.length - 1; i++) {
            for (int j = 0; j < num.length - i - 1; j++) {
                if (num[j] > num[j + 1]) {
                    temp = num[j];
                    num[j] = num[j + 1];
                    num[j + 1] = temp;
                }
            }
        }
        return num;
    }

    /**
     * 获取一组数中的最大的数
     *
     * @param num
     * @return
     */
    public static int getMax(int[] num) {
        int max = num[0];
        for (int tNum : num) {
            if (max < tNum) {
                max = tNum;
            }
        }
        return max;
    }

    /**
     * 检查一个数是否包涵在一个数组中
     *
     * @param num
     * @param numarr
     * @return
     */
    public static boolean isInArr(int num, int[] numarr) {
        boolean temp = false;
        for (int i = 0; i < numarr.length; i++) {
            if (numarr[i] == num) {
                temp = true;
                break;
            }
        }
        return temp;
    }

    /**
     * 检查一个数是否包涵在一个List<Integer>中
     *
     * @param num
     * @param numarr
     * @return
     */
    public static boolean isInArr(int num, List<Integer> numarr) {
        boolean temp = false;
        for (int i = 0; i < numarr.size(); i++) {
            if (numarr.get(i) == num) {
                temp = true;
                break;
            }
        }
        return temp;
    }

    /**
     * int 数组去除重复元素
     *
     * @param num
     * @return
     */
    public static int[] filterRepeat(int[] num) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < num.length; i++) {
            if (!isInArr(num[i], list)) {
                list.add(num[i]);
            }
        }
        int[] tNum = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            tNum[i] = list.get(i);
        }
        return tNum;
    }

    /**
     * 检验numArr这个整数集合是否以startIndex开始有len个连续自然数
     *
     * @param numArr
     * @param startIndex
     * @param len
     * @return
     */
    public static boolean checkConsecutiveNaturalNumbers(int[] numArr, int startIndex, int len) {
        for (int i = startIndex + 1; i < startIndex + len; i++) {
            if (numArr[i - 1] + 1 != numArr[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 检验numArr这个整数集合是否以startNum开始有len个连续自然数
     *
     * @param numArr
     * @param startNum
     * @param len
     * @return
     */
    public static boolean checkConsecutiveNaturalNumbersOfNum(int[] numArr, int startNum, int len) {
        int index = -1;
        for (int i = 0; i < numArr.length; i++) {
            if (numArr[i] == startNum) {
                index = i;
            }
        }
        if (-1 == index) {
            return false;
        }
        try {
            for (int i = index; i < index + len - 1; i++) {
                if (numArr[i] + 1 != numArr[i + 1]) {
                    return false;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

}
